package com.xquant.pricing.pricingConfig.service.impl;

import com.github.pagehelper.PageInfo;
import com.xquant.common.security.utils.SecurityUtils;
import com.xquant.pricing.pricingConfig.mapper.PricingConfigAuthorMapper;
import com.xquant.pricing.pricingConfig.service.PricingConfigAuthorService;
import com.xquant.pricing.pricingConfig.service.PricingConfigAuthorServiceWrapper;
import org.apache.commons.collections.MapUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * @Auther: B946
 * @Date: 23/04/2020 11:26
 * @Description:
 */
@Component(PricingConfigAuthorServiceWrapper.BEAN_NAME)
public class PricingConfigAuthorServiceWrapperImpl implements PricingConfigAuthorServiceWrapper, InitializingBean {


    @Autowired
    private List<PricingConfigAuthorService> pricingConfigAuthorServices;

    @Autowired
    private PricingConfigAuthorMapper pricingConfigAuthorMapper;



    private Map<String, PricingConfigAuthorService> map = new HashMap<>();

    @Override
    public void savePricingConfig(Map params) {
        PricingConfigAuthorService service = getDeletegate(params);
        service.savePricingConfig(params);
    }

    @Override
    public void updatePricingConfig(Map params) {
        PricingConfigAuthorService service = getDeletegate(params);
        service.updatePricingConfig(params);
    }

    @Override
    public void deletePricingConfig(Map<String, Object> params) {
        PricingConfigAuthorService service = getDeletegate(params);

        pricingConfigAuthorMapper.removeDeptPermCfg(params);
        pricingConfigAuthorMapper.removeUserPermCfg(params);

        service.deletePricingConfig(params);
    }

    @Override
    public void deletePricingConfigSyncAuthor(Map<String, Object> params) {
        PricingConfigAuthorService service = getDeletegate(params);
        service.deletePricingConfigSyncAuthor(params);
    }

    @Override
    public void savePricingConfigSyncAuthor(Map<String, Object> params) {
        PricingConfigAuthorService service = getDeletegate(params);
        service.savePricingConfigSyncAuthor(params);
    }

    @Override
    public PageInfo<Map> queryPricingConfigAuthorByPage(Map params) {
        PricingConfigAuthorService service = getDeletegate(params);
        return service.queryPricingConfigAuthorByPage(params);
    }

    @Override
    public PageInfo<Map> queryGroupPricingConfigAuthorByPage(Map<String, Object> params) {
        PricingConfigAuthorService service = getDeletegate(params);
        return service.queryGroupPricingConfigAuthorByPage(params);
    }

    @Override
    public List<Map> queryPricingConfigAuthor(Map params) {
        PricingConfigAuthorService service = getDeletegate(params);
        return service.queryPricingConfigAuthor(params);
    }

    @Override
    public PageInfo<Map> queryPricingUserAuthorByPage(Map params) {
        PricingConfigAuthorService service = getDeletegate(params);
         PageInfo<Map> pageInfo =  service.queryPricingUserAuthorByPage(params);
        return pageInfo;
    }

    @Override
    public void savePricingConfigUserAuthor(Map params) {
        PricingConfigAuthorService service = getDeletegate(params);
        service.savePricingConfigUserAuthor(params);
    }

    @Override
    public void updatePricingConfigUserAuthor(Map params) {
        PricingConfigAuthorService service = getDeletegate(params);
        service.updatePricingConfigUserAuthor(params);
    }

    @Override
    public void deletePricingConfigUserAuthor(Map params) {
        PricingConfigAuthorService service = getDeletegate(params);
        service.deletePricingConfigUserAuthor(params);
    }

    @Override
    public void deleteUserPriceCfg(Map params) {
        PricingConfigAuthorService service = getDeletegate(params);
        service.deleteUserPriceCfg(params);
    }

    @Override
    public PageInfo<Map> queryPricingConfigUserAuthor(Map params) {
        PricingConfigAuthorService service = getDeletegate(params);
        return service.queryPricingConfigUserAuthor(params);
    }

    @Override
    public List<Map> queryPricingConfigUserDefaultAuthor(Map params) {
        PricingConfigAuthorService service = getDeletegate(params);
        return service.queryPricingConfigUserDefaultAuthor(params);
    }

    @Override
    public void executePricingConfigSyncAuthor(Map<String, Object> params) {
        PricingConfigAuthorService service = getDeletegate(params);
        service.executePricingConfigSyncAuthor(params);
    }

    @Override
    public void updateUserDefaultPricingParam(Map<String, Object> params) {
        PricingConfigAuthorService service = getDeletegate(params);
        //将原定价配置默认取消并将新的定价配置更改为默认
        service.updateUserDefaultPricingParam(params);
        HashMap<String, Object> hashMap = new HashMap<>();
        hashMap.put("userId", params.get("userId"));
        hashMap.put("cfgId",params.get("cfgId"));
        //更新所有部门都拥有该权限
        service.updateDefaultOtherAccRight(hashMap);
        //更新所有用户权限 为只读
        service.selectDefaultOtherPerm(hashMap);
        //更新定价配置内的浮动参数，并将所有用户(不更改原有权限，其余的赋为只读)和部门(写权限)都赋予权限
        service.updateUserPermByFloatConfig(hashMap);
    }

    @Override
    public void updateGroupPerm(Map<String, Object> param) {
        pricingConfigAuthorMapper.removeUserPermCfg(param);
        pricingConfigAuthorMapper.removeDeptPermCfg(param);
        pricingConfigAuthorMapper.updateUserPermCfg(param);
        pricingConfigAuthorMapper.updateDeptPermCfg(param);
    }

    @Override
    public List getGroupUserAndDeptPerm(Map<String, Object> param) {
        List<String> userPermUserId = pricingConfigAuthorMapper.getUserPermUserId(param);
        List<String> deptPermDeptId = pricingConfigAuthorMapper.getDeptPermDeptId(param);
        userPermUserId.addAll(deptPermDeptId);
        return userPermUserId;
    }

    @Override
    public void insertUserCfgRight(List<Map<String,Object>> list) {
        pricingConfigAuthorMapper.batchInsertCfgUser(list);
    }

    @Override
    public void insertDeptCfgRight(Map map) {
        pricingConfigAuthorMapper.batchInsertCfgDept(map);
    }

    @Override
    public void removeUserPermCfg(Map param) {
        param.put("accId",String.valueOf(param.get("accId")));
        pricingConfigAuthorMapper.removeUserPermCfgByUserId(param);
    }

    @Override
    public void removeDeptPermCfg(Map param) {
        param.put("accId",String.valueOf(param.get("accId")));
        pricingConfigAuthorMapper.removeDeptPermCfgByDeptId(param);
    }

    @Override
    public void updateCfgUserPerm(Map<String, Object> params) {

        pricingConfigAuthorMapper.updateUserPermCfg(params);
    }

    @Override
    @Transactional
    public void doSavePricingConfig(Map<String, Object> param) {

        /*****************************权限部分*****************************************/
        ArrayList<String> userPerms = new ArrayList<>();
        ArrayList<String> deptPerms = new ArrayList<>();
        /** 为读写表赋权*/
        //存放创建人所属部门和上级部门，必须写权限
        ArrayList<String> deptAncestors = new ArrayList<>();
        //存放其他部门
        ArrayList<String> anotherDepts = new ArrayList<>();
        //存放其他人的数组
        ArrayList<String> anotherUser = new ArrayList<>();

        Map<String,Object> deptCfgRights = new HashMap<>();
        Map<String,Object> anotherDeptCfgRights = new HashMap<>();



        String allocateDeptAndUsers = param.get("allocateDeptAndUser").toString();
        String userId = String.valueOf(SecurityUtils.getUserId());
        String cfgId = String.valueOf(param.get("cfgId"));
        String cfgRight = String.valueOf(param.get("cfgRight"));
        HashMap map= com.alibaba.fastjson2.JSONObject.parseObject(cfgRight,HashMap.class);
        //创建人所属部门
        String createDeptId = SecurityUtils.getLoginUser().getSysUser().getDeptId().toString();
        deptAncestors.add(createDeptId);

        //将创建人所属部门的上级部门加入deptPerms
        /*String deptAncestorIds = groupService.getDeptAncestors(createDeptId);
        List<String> deptAncestorIdArrs = Arrays.asList(deptAncestorIds.split(","));
        for (String deptAncestorArr : deptAncestorIdArrs) {
            if ("0".equals(deptAncestorArr) != true) {
                deptPerms.add(deptAncestorArr);
                deptAncestors.add(deptAncestorArr);
            }
        }*/

        for (String allocateDeptAndUser : allocateDeptAndUsers.split(",")) {
            if (allocateDeptAndUser.charAt(0) == 'u') {
                userPerms.add(allocateDeptAndUser.substring(2));
                if(!userId.equals(allocateDeptAndUser.substring(2))){
                    //不是本人，赋予传过来的权限
                    anotherUser.add(allocateDeptAndUser.substring(2));
                }
            } else if (allocateDeptAndUser.charAt(0) == 'd') {
                deptPerms.add(allocateDeptAndUser.substring(2));
                if(!createDeptId.equals(allocateDeptAndUser.substring(2))){
                    //不是所属部门，赋予传过来的权限
                    anotherDepts.add(allocateDeptAndUser.substring(2));
                }
            }
        }
        if (userPerms.size() > 0) {
            param.put("userIds", userPerms);
        }
        if (deptPerms.size() > 0) {
            param.put("deptIds", deptPerms);
        }
        List<Map<String,Object>>  anotherUserList=new ArrayList<>();
        //为创建人单独赋写权限
        Map<String,Object> userCfgRights = new HashMap<>();
        userCfgRights.put("userId",userId);
        userCfgRights.put("cfgId",cfgId);
        userCfgRights.put("cfgRight","2");
        anotherUserList.add(userCfgRights);

        //其他人传过来的权限
        if(anotherUser.size() != 0){
            for (String authId:anotherUser) {
                Map<String,Object> anotherUserCfgRights = new HashMap<>();
                anotherUserCfgRights.put("userId", authId);
                anotherUserCfgRights.put("cfgId", cfgId);
                anotherUserCfgRights.put("cfgRight", map.get(authId).toString());
                anotherUserList.add(anotherUserCfgRights);
            }
        }
        insertUserCfgRight(anotherUserList);
        //为所属部门和上级部门单独赋写权限
        deptCfgRights.put("deptIds",deptAncestors);
        deptCfgRights.put("cfgId",cfgId);
        deptCfgRights.put("cfgRight","2");
        insertDeptCfgRight(deptCfgRights);
        //为其他部门赋传过来的权限
        anotherDepts.removeAll(deptAncestors);
        if(anotherDepts.size() != 0){
            anotherDeptCfgRights.put("deptIds",anotherDepts);
            anotherDeptCfgRights.put("cfgId",cfgId);
            anotherDeptCfgRights.put("cfgRight","2");
            insertDeptCfgRight(anotherDeptCfgRights);
        }

        /*******************************************************************************/
    }

    @Override
    @Transactional
    public void doUpdatePricingConfigUserAuthor(Map<String, Object> params) {

        List<Integer> userIds = (List<Integer>) params.get("userIds");
        String cfgRight = String.valueOf(params.get("cfgRight"));
        String productType = String.valueOf(params.get("productType"));
        String deptId = String.valueOf(params.get("deptId"));
        //存放上级部门
        ArrayList<String> deptAncestors = new ArrayList<>();
        //将创建人所属部门的上级部门加入deptPerms
      /*  String deptAncestorIds = groupService.getDeptAncestors(deptId);
        List<String> deptAncestorIdArrs = Arrays.asList(deptAncestorIds.split(","));
        for (String deptAncestorArr : deptAncestorIdArrs) {
            if ("0".equals(deptAncestorArr) != true) {
                deptAncestors.add(deptAncestorArr);
            }
        }*/

        for(Integer userId : userIds){
            Map<String,Object> param = new HashMap<>();
            param.put("userId",userId);
            param.put("cfgId",params.get("cfgId"));
            param.put("deptId",deptId);
            param.put("cfgRight",cfgRight);
            param.put("productType",productType);
            if("1".equals(pricingConfigAuthorMapper.queryCfgFlagByUserId(String.valueOf(userId)))){
                List<Map> list = pricingConfigAuthorMapper.queryCfgDept(param);
                if (list.size() == 0 && !"0".equals(cfgRight)) {
                    pricingConfigAuthorMapper.saveCfgDept(param);
                } else if(list.size() != 0 && !"0".equals(cfgRight)){
                    pricingConfigAuthorMapper.updateCfgDept(param);
                }else if(list.size() != 0 && "0".equals(cfgRight)){
                    pricingConfigAuthorMapper.deleteCfgDept(param);
                }
                removeDeptPermCfg(param);
                if(!"0".equals(cfgRight)) {
                    params.put("deptIds",Arrays.asList(deptId));
                    pricingConfigAuthorMapper.updateDeptPermCfg(params);
                    Map<String,Object> deptParams = new HashMap<>();
                    deptParams.put("deptIds",deptAncestors);
                    deptParams.put("cfgId",params.get("cfgId"));
                    deptParams.put("cfgRight",2);
                    for(String deId : deptAncestors){
                        deptParams.put("deptId",deId);
                        pricingConfigAuthorMapper.deleteCfgDept(deptParams);
                        pricingConfigAuthorMapper.saveCfgDept(deptParams);
                        removeDeptPermCfg(deptParams);
                    }
                    if(deptAncestors.size()>0){
                        pricingConfigAuthorMapper.updateDeptPermCfg(deptParams);
                    }

                }

            }else{
                List<Map> list = queryPricingConfigUserAuthor(param).getList();
                if (list.size() == 0 && !"0".equals(cfgRight)) {
                    savePricingConfigUserAuthor(param);
                } else if(list.size() != 0 && !"0".equals(cfgRight)){
                    updatePricingConfigUserAuthor(param);
                }else if(list.size() != 0 && "0".equals(cfgRight)){
                    deleteUserPriceCfg(param);
                }
                removeUserPermCfg(param);
            }

        }
        if(!"0".equals(cfgRight)) {
            updateCfgUserPerm(params);
        }
    }


    private PricingConfigAuthorService getDeletegate(Map params) {
        String productType = MapUtils.getString(params, "productType");
        return map.get(productType);
    }

    @Override
    public void afterPropertiesSet() throws Exception {

        for (PricingConfigAuthorService service : pricingConfigAuthorServices) {
            for (String productType : service.getSupportedProductTypes()) {
                map.put(productType, service);
            }
        }
    }

    @Override
    public boolean checkCfgName(Map map) {
        Map resMap = pricingConfigAuthorMapper.checkCfgName(map);
        if(resMap == null){
            return true;
        }else{
            if(map.get("cfgId").equals(resMap.get("CFG_ID"))){
                return true;
            }else{
                return false;
            }
        }
    }
}
